﻿using ExcellentProjectPlus.Dominio.Cuestionarios.Entidades;
using ExcellentProjectPlus.Dominio.Cuestionarios.Servicios.Preguntas;
using System;
using System.Collections.Generic;
using System.Transactions;
using ExcellentProjectPlus.Aplicacion.Catalogos.Catalogos;
using ExcellentProjectPlus.Dominio.Catalogos.Entidades;
using System.Linq;

namespace ExcellentProjectPlus.Aplicacion.Cuestionarios.Preguntas
{
    public class ServicioDeGestionDePreguntas
        : IServicioDeGestionDePreguntas
    {
        #region Propiedades
        IServicioDeAdministracionDePreguntas _servicioDeAdministracionDePreguntas;
        IServicioDeGestionDeCatalogos _servicioDeGestionDeCatalogos;
        #endregion

        #region Constructores
        public ServicioDeGestionDePreguntas(IServicioDeAdministracionDePreguntas servicioDeAdministracionDePreguntas,
            IServicioDeGestionDeCatalogos servicioDeGestionDeCatalogos)
        {
            _servicioDeAdministracionDePreguntas = servicioDeAdministracionDePreguntas;
            _servicioDeGestionDeCatalogos = servicioDeGestionDeCatalogos;
        }
        #endregion
        public IEnumerable<Pregunta> ObtenerPreguntas()
        {
            IEnumerable<Pregunta> resultado = null;
            var trxOptions = new TransactionOptions();
            //Lectura con nivel de aislamiento ReadUncommited para evitar bloqueos en la base
            trxOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
            trxOptions.Timeout = TimeSpan.FromMinutes(2);
            using (var transaccion = new TransactionScope(TransactionScopeOption.RequiresNew, trxOptions))
            {
                resultado = _servicioDeAdministracionDePreguntas.ObtenerPreguntas();
                transaccion.Complete();
            }

            return resultado;
        }

        public Pregunta ObtenerPreguntaPorId(int id)
        {
            Pregunta resultado = null;
            var trxOptions = new TransactionOptions();
            //Lectura con nivel de aislamiento ReadUncommited para evitar bloqueos en la base
            trxOptions.IsolationLevel = IsolationLevel.ReadCommitted;
            trxOptions.Timeout = TimeSpan.FromMinutes(2);
            using (var transaccion = new TransactionScope(TransactionScopeOption.RequiresNew, trxOptions))
            {
                resultado = _servicioDeAdministracionDePreguntas.ObtenerPreguntaPorId(id);
                transaccion.Complete();
            }

            return resultado;
        }

        public void AgregarPregunta(Pregunta pregunta)
        {
            _servicioDeAdministracionDePreguntas.AgregarPregunta(pregunta);
        }

        public void ModificarPregunta(Pregunta pregunta)
        {
            _servicioDeAdministracionDePreguntas.ModificarPregunta(pregunta);
        }

        public void EliminarPregunta(Pregunta pregunta)
        {
            _servicioDeAdministracionDePreguntas.EliminarPregunta(pregunta);
        }

        public IEnumerable<Pregunta> ObtenerPreguntasPaginado(int pagina, int tamanio)
        {
            return _servicioDeAdministracionDePreguntas.ObtenerPreguntasPaginado(pagina, tamanio);
        }
        public void Dispose()
        {
            throw new NotImplementedException();
        }


        public List<Pregunta> ObtenerPreguntaConOpciones(int idPregunta)
        {
            return _servicioDeAdministracionDePreguntas.ObtenerPreguntaConOpciones(idPregunta);
        }

        public IEnumerable<object> ObtenerPreguntasConDetalle()
        {
            IEnumerable<Pregunta> resultado = null;
            var trxOptions = new TransactionOptions();
            //Lectura con nivel de aislamiento ReadUncommited para evitar bloqueos en la base
            trxOptions.IsolationLevel = IsolationLevel.ReadUncommitted;
            trxOptions.Timeout = TimeSpan.FromMinutes(2);

            IEnumerable<Catalogo> catalogos = null;

            using (var transaccion = new TransactionScope(TransactionScopeOption.RequiresNew, trxOptions))
            {
                catalogos = _servicioDeGestionDeCatalogos.ObtenerCatalogos();
                transaccion.Complete();
            }

            using (var transaccion = new TransactionScope(TransactionScopeOption.RequiresNew, trxOptions))
            {
                resultado = _servicioDeAdministracionDePreguntas.ObtenerPreguntas();
                transaccion.Complete();
            }

            Catalogo catalogoPregunta, tipoPregunta, areaPregunta;
            var datos = resultado.Select(p =>
                {
                    catalogoPregunta = catalogos.FirstOrDefault(c =>
                        (c.ValorCatalogo == p.CodigoCategoria && c.Clave == "CategoriaPregunta"));
                    tipoPregunta = catalogos.FirstOrDefault(c =>
                        c.ValorCatalogo == p.CodigoTipo && c.Clave == "TipoPregunta");
                    areaPregunta = catalogos.FirstOrDefault(c =>
                        c.ValorCatalogo == p.CodigoArea && c.Clave == "AreaPregunta");
                    return new
                    {
                        IdPregunta = p.IdPregunta,
                        CodigoArea = p.CodigoArea,
                        CodigoCategoria = p.CodigoCategoria,
                        CodigoTipo = p.CodigoTipo,
                        Enunciado = p.Enunciado,
                        Estado = p.Estado,
                        Categoria = ((catalogoPregunta == null) ? "Ninguna" : catalogoPregunta.NombreCatalogo),
                        Tipo = ((tipoPregunta == null) ? "Ninguno" : tipoPregunta.NombreCatalogo),
                        Area = ((areaPregunta == null) ? "Ninguna" : areaPregunta.NombreCatalogo)
                    };
                });

            return datos;
        }

        public void AgregarRecursoACuestionario(int idCuestionario, int idRecurso)
        {
            _servicioDeAdministracionDePreguntas.AgregarRecursoACuestionario(idCuestionario, idRecurso);
        }

        public Pregunta ObtenerPreguntaCompletaPorId(int id)
        {
            return _servicioDeAdministracionDePreguntas.ObtenerPreguntaConOpciones(id).FirstOrDefault();
        }

        public void EditarRecursoAPregunta(int idPregunta, int item)
        {
            throw new NotImplementedException();
        }
    }
}
